// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import Foundation

/// A type that represents a remote image generation model (like Imagen), with the ability to
/// generate
/// images based on various input types.
///
/// **Public Preview**: This API is a public preview and may be subject to change.
@available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *)
public final class TemplateImagenModel: Sendable {
  let generativeAIService: GenerativeAIService
  let apiConfig: APIConfig

  init(generativeAIService: GenerativeAIService, apiConfig: APIConfig) {
    self.generativeAIService = generativeAIService
    self.apiConfig = apiConfig
  }

  /// Generates images from a prompt template and variables.
  ///
  /// - Parameters:
  ///   - template: The prompt template to use.
  ///   - variables: A dictionary of variables to substitute into the template.
  ///   - options: The ``RequestOptions`` for the request, currently used to override default
  /// request timeout.
  /// - Returns: The images generated by the model.
  /// - Throws: An error if the request failed.
  public func generateImages(templateID: String,
                             inputs: [String: Any],
                             options: RequestOptions = RequestOptions()) async throws
    -> ImagenGenerationResponse<ImagenInlineImage> {
    let templateInputs = try inputs.mapValues { try TemplateInput(value: $0) }
    let projectID = generativeAIService.firebaseInfo.projectID
    let request = TemplateImagenGenerationRequest<ImagenInlineImage>(
      template: templateID,
      inputs: templateInputs,
      projectID: projectID,
      apiConfig: apiConfig,
      options: options
    )
    return try await generativeAIService.loadRequest(request: request)
  }
}
